#include "param_store.h"
#include "radio.h"
#include "lib.h"
#include "can.h"
#include "flash.h"

void board_reset(void)
{
	if ((receive_message_bootloader.rx_data[0] == 0x3) &&
		(receive_message_bootloader.rx_data[4] == 0x43) &&
		(receive_message_bootloader.rx_data[5] == 0x34) &&
		(receive_message_bootloader.rx_data[6] == 0x5A) &&
		(receive_message_bootloader.rx_data[7] == 0xA5))
	{
		if (Flash_erase_onePage((uint32_t)DOWNLOADE_INFORMATION_ADDR_BASE) < 0)//擦除存储下载有效信息的区域
		{
			return;
		}
		NVIC_SystemReset();
		while (1);
	}
}
uint16_t us_set_radio_tx_addr = RADIO_TX_ADDR;
uint16_t us_set_radio_rx_addr = RADIO_RX_ADDR;
uint8_t uc_set_radio_channel  = 0;

typedef union param_radio{
	uint32_t buf[32];
     
    struct{
        uint32_t head;/*0x5A5A A5A5*/
        uint32_t radio_tx_addr;
        uint32_t radio_rx_addr;
        uint32_t radio_channel;
    }data;
}parameter_radio_t;
/**
 * @brief  无线参数初始化
 */
void param_radio_data_init(void)
{
    parameter_radio_t param;

    memset(&param,0,sizeof(parameter_radio_t));
    fmc_read_32bit_data(USER_PARAM_BASE_ADDR, sizeof(parameter_radio_t)/sizeof(uint32_t), (int32_t *)&param.buf[0]);
    if(param.data.head == 0x5A5AA5A5)
    {
        us_set_radio_tx_addr = param.data.radio_tx_addr;
        us_set_radio_rx_addr = param.data.radio_rx_addr;
        uc_set_radio_channel = param.data.radio_channel;

        us_radio_rx_addr = us_set_radio_rx_addr;
        us_radio_tx_addr = us_set_radio_tx_addr;
        uc_radio_channel = uc_set_radio_channel;
    }
}

int8_t param_store_radio_to_flash(void)
{
    parameter_radio_t param;
    uint32_t tRadio_tx_addr = 0;
    uint32_t tRadio_rx_addr = 0;
    uint32_t tRadio_channel = 0;
    
    fmc_read_32bit_data(USER_PARAM_BASE_ADDR, sizeof(parameter_radio_t)/sizeof(uint32_t), (int32_t *)&param.buf[0]);
    if(param.data.head == 0x5A5AA5A5)
    {
        if((param.data.radio_tx_addr != us_set_radio_tx_addr) || (param.data.radio_channel != uc_set_radio_channel))
        {
            param.data.radio_tx_addr = us_set_radio_tx_addr;
            param.data.radio_rx_addr = us_set_radio_rx_addr;
            param.data.radio_channel = uc_set_radio_channel;
            if(Flash_erase_onePage(USER_PARAM_BASE_ADDR) == 0)
            {
                fmc_write_32bit_data_with_sector_erased(USER_PARAM_BASE_ADDR, sizeof(parameter_radio_t)/sizeof(uint32_t), &param.buf[0]);
            }
            memset(&param,0,sizeof(parameter_radio_t));
            fmc_read_32bit_data(USER_PARAM_BASE_ADDR, sizeof(parameter_radio_t)/sizeof(uint32_t), (int32_t *)&param.buf[0]);
            if(param.data.head == 0x5A5AA5A5)
            {
                tRadio_tx_addr = param.data.radio_tx_addr;
                tRadio_rx_addr = param.data.radio_rx_addr;
                tRadio_channel = param.data.radio_channel;

                if((tRadio_tx_addr == us_set_radio_tx_addr) && (tRadio_rx_addr == us_set_radio_rx_addr) && (tRadio_channel == uc_set_radio_channel)) return 1;
                else return 0;
            }
            else return 0;
        }
        else
        {
            return -1;/*参数没有变化*/
        }
    }
    else
    {
        param.data.head = 0x5A5AA5A5;
        param.data.radio_tx_addr = us_set_radio_tx_addr;
        param.data.radio_rx_addr = us_set_radio_rx_addr;
        param.data.radio_channel = uc_set_radio_channel;

        if(Flash_erase_onePage(USER_PARAM_BASE_ADDR) == 0)
        {
            fmc_write_32bit_data_with_sector_erased(USER_PARAM_BASE_ADDR, sizeof(parameter_radio_t)/sizeof(uint32_t), &param.buf[0]);
        }
        memset(&param,0,sizeof(parameter_radio_t));
        fmc_read_32bit_data(USER_PARAM_BASE_ADDR, sizeof(parameter_radio_t)/sizeof(uint32_t), (int32_t *)&param.buf[0]);
        if(param.data.head == 0x5A5AA5A5)
        {
            tRadio_tx_addr = param.data.radio_tx_addr;
            tRadio_rx_addr = param.data.radio_rx_addr;
            tRadio_channel = param.data.radio_channel;

            if((tRadio_tx_addr == us_set_radio_tx_addr) && (tRadio_rx_addr == us_set_radio_rx_addr) && (tRadio_channel == uc_set_radio_channel)) return 1;
            else return 0;
        }
        else return 0;
    }
}
uint8_t uc_boot_can_rx_flag = 0;
param_store_t uc_param_store_finish_flag = eParam_store_nothing;/*参数设置完成标志，1：设置成功；2：参数相等，3：设置失败*/
uint8_t uc_set_cmd = 0;/*1:设置地址通道；2：读地址通道*/
/**
 * 
 */
void param_store_run(void)
{
    uint8_t buf[16] = { 0 };
    int8_t temp = 0;
    uint8_t cmd = 0;
    uint8_t len = 0;
    if (uc_boot_can_rx_flag == 0) return;
    uc_boot_can_rx_flag = 0;
    
    board_reset();
    cmd = receive_message_bootloader.rx_data[0];
    switch(cmd)
    {
        case 0x04:/*设置地址通道*/
            uc_set_radio_channel = receive_message_bootloader.rx_data[1];
            us_set_radio_tx_addr = (receive_message_bootloader.rx_data[2]<<0) | (receive_message_bootloader.rx_data[3]<<8);
            us_set_radio_rx_addr = (receive_message_bootloader.rx_data[4]<<0) | (receive_message_bootloader.rx_data[5]<<8);
            temp = param_store_radio_to_flash();
            if(temp == 1)  /*设置成功*/
            {
                uc_param_store_finish_flag = eParam_store_success;
                buf[0] = cmd;
                buf[1] = 0;
                DRV_CANBUS_Send(ACK_TX_ID, 0, buf, 8);
            }
            else if(temp == 0) /*设置失败*/
            {
                uc_param_store_finish_flag = eParam_store_fail;
            }
            else if(temp == -1) /*设置参数相等*/
            {
                uc_param_store_finish_flag = eParam_store_equal;
            }
            break;
        case 0x05:/*读取通道地址*/
            buf[len] = cmd;
            len++;
            buf[len] = uc_set_radio_channel;
            len++;
            buf[len] = (us_set_radio_tx_addr>>0)&0xFF;
            len++;
            buf[len] = (us_set_radio_tx_addr>>8)&0xFF;
            len++;
            buf[len] = (us_set_radio_rx_addr>>0)&0xFF;
            len++;
            buf[len] = (us_set_radio_rx_addr>>8)&0xFF;
            len++;
            DRV_CANBUS_Send(ACK_TX_ID, 0, buf, 8);
            break;
        default:
        break;
    }
}

//800mA对应的值；
uint16_t g_800_ma[HEM_PWMI_NUM] = { 0 };
uint16_t g_200_ma[HEM_PWMI_NUM] = { 0 };
void param_pwmi_data_init(void)
{
  uint16_t read_buf[30]  = { 0 };
  uint16_t i = 0;
  int8_t success = 0;
  for(i = 0;i < HEM_PWMI_NUM;i++)
  {
    g_200_ma[i] = 200;
    g_800_ma[i] = 800;
  }
  fmc_read_16bit_data(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(read_buf)/2,(int16_t *)read_buf);
  if((read_buf[0]  == 0x5A5A) && (read_buf[29] == 0xA5A5))
  {
    for(i = 0;i < HEM_PWMI_NUM;i++)
    {
      if((read_buf[i+1] < 120) || (read_buf[i+1] > 280))
      {
        success = -1;
        break;
      }
      if((read_buf[i+15] < 600) || (read_buf[i+15] > 1000))
      {
        success = -1;
        break;
      }
    }

    if(success == 0)
    {
      Lib_memcpy(g_200_ma,&read_buf[1],sizeof(g_200_ma)/2);
      Lib_memcpy(g_800_ma,&read_buf[15],sizeof(g_800_ma)/2);
    }
  }
}
uint8_t g_pwmi_store_param_sn = 0;
void param_store_pwmi_to_flash(void)
{
  uint16_t write_buf[30] = { 0 };
  uint16_t read_buf[30]  = { 0 };
  int a = 0,b = 0;
  if(g_pwmi_store_param_sn == 0) return;
  g_pwmi_store_param_sn = 0;

  fmc_read_16bit_data(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(read_buf)/2,(int16_t *)read_buf);
  if((read_buf[0]  == 0x5A5A) && (read_buf[29] == 0xA5A5))
  {
    a = Lib_memcmp(&read_buf[1],g_200_ma,sizeof(g_200_ma)/2);
    b = Lib_memcmp(&read_buf[13],g_800_ma,sizeof(g_800_ma)/2);
    if((a != 0) || (b != 0))
    {
      write_buf[0]  = 0x5A5A;
      write_buf[29] = 0xA5A5;
      Lib_memcpy(&write_buf[1], g_200_ma,sizeof(g_200_ma)/2);
      Lib_memcpy(&write_buf[15],g_800_ma,sizeof(g_800_ma)/2);

      Flash_erase_onePage((uint32_t)PWMI_CALIBRATION_DATA_ADDR_BASE);
      fmc_write_16bit_data_with_sector_erased(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(write_buf)/2,write_buf);
    }
  }
  else
  {
    write_buf[0]  = 0x5A5A;
    write_buf[29] = 0xA5A5;
    Lib_memcpy(&write_buf[1], g_200_ma,sizeof(g_200_ma)/2);
    Lib_memcpy(&write_buf[15],g_800_ma,sizeof(g_800_ma)/2);

    Flash_erase_onePage((uint32_t)PWMI_CALIBRATION_DATA_ADDR_BASE);
    fmc_write_16bit_data_with_sector_erased(PWMI_CALIBRATION_DATA_ADDR_BASE,sizeof(write_buf)/2,write_buf);
  }

}

